package com.xyxy.platform.modules.core.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 常用的系统工具类,查询系统信息
 * 参考: http://blog.csdn.net/blue_jjw/article/details/8741000
 * http://hi.baidu.com/qmiao128/item/ec22490f1e33047dbfe97e3a
 * Time: 下午2:38
 * To change this template use File | Settings | File Templates.
 */
public class SystemUtils {
    private static Logger log = LoggerFactory.getLogger(SystemUtils.class);

    private static final String CPU_COMMAND = "top -b -n 1";
    private static final String IDLE_CPU_PATTERN = "([1-9]+[0-9]*|0)(\\.[\\d]+)?%id";
    private static final String MEM_PATTERN = "([1-9]+[0-9]*|0)(\\.[\\d]+)?k";

    public static OSComInfo getOSComInfo() throws Exception {
        OSComInfo result = new OSComInfo();
        Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec(CPU_COMMAND);// call "top" command in linux
        /**
         top - 15:27:08 up 29 days,  5:27,  2 users,  load average: 0.69, 0.86, 0.85
         Tasks:  87 total,   1 running,  86 sleeping,   0 stopped,   0 zombie
         Cpu(s):  2.6%us,  0.1%sy,  0.0%ni, 96.4%id,  0.7%wa,  0.1%hi,  0.1%si,  0.0%st
         Mem:   4054168k total,  3982664k used,    71504k free,   253068k buffers
         Swap:  4104596k total,    37448k used,  4067148k free,  1152544k cached

         PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
         4214 mysql     15   0  942m 282m 5672 S 99.5  7.1   1232:20 mysqld
         29756 root      18   0 2771m 1.3g  11m S  2.0 34.5  29:22.05 java
         */
        try (BufferedReader in =
                     new BufferedReader(new InputStreamReader(process.getInputStream()))) {
            String str = null;
            while ((str = in.readLine()) != null) {
                if (str.startsWith("Cpu(s):")) {
                    Pattern pattern = Pattern.compile(IDLE_CPU_PATTERN);
                    Matcher m = pattern.matcher(str);
                    if (m.find()) {
                        result.setCpu(100 - Float.parseFloat(m.group().replace("%id", "")));
                    }
                } else if (str.startsWith("Mem:")) {
                    Pattern pattern = Pattern.compile(MEM_PATTERN);
                    Matcher matcher = pattern.matcher(str);
                    int matchCount = 0;
                    float memUsed = 0;
                    while (matcher.find()) {
                        float tempData = Float.parseFloat(matcher.group().replace("k", ""));
                        if (matchCount == 0) {
                            //total
                            result.setMemory(tempData);
                        } else if (matchCount == 1) {
                            //used
                            memUsed += tempData;
                        } else if (matchCount == 3) {
                            //buffers
                            memUsed -= tempData;
                        }
                        log.info(matcher.group().replace("%id", ""));
                        matchCount++;
                    }
                    result.setMemory(memUsed / result.getMemory());
                }
            }
        } catch (Exception ex) {
            log.error("获取CPU信息异常", ex);
        }
        return result;
    }

    public static void main(String[] args) {
        try {
            Pattern p = Pattern.compile("([1-9]+[0-9]*|0)(\\.[\\d]+)?k");
            Matcher m = p.matcher("Mem:   4054168k total,  3982664k used,    71504k free,   253068k buffers");
            while (m.find()) {
                log.info(m.group().replace("%id", ""));
            }
            log.info("usage:{}", (3982664.0 - 253068) / 4054168);
//            System.out.println(SystemUtils.getCpuUsage());
//            System.out.println(SystemUtils.getMemUsage());
        } catch (Exception ex) {
            log.error("出现异常", ex);
        }
    }
}
